import sys
parent_dir = "../pygl"
sys.path.append(parent_dir)
import OpenGL.GL as gl
import glm
import imgui
import numpy as np
from PIL import Image
from common.app_v1 import App
import pygl

class TextureWrapApp(App):
    # 初始化着色器，vao vbo等
    def setupVertex(self) -> None:
        self.program = pygl.ProgramVF("basic/shaders/texture.vs", 
                                      "basic/shaders/texture.fs")
        rect_width = 0.8
        rect_height = 0.8
        vertices = np.array([
            # 位置                                      # 颜色          # 纹理坐标
            rect_width / 2.0, rect_height / 2.0, 0.0,   0.0, 0.0, 1.0,  2.0, 2.0,
            rect_width / 2.0, -rect_height / 2.0, 0.0,  0.0, 0.0, 1.0,  2.0, -1.0,
            -rect_width / 2.0, -rect_height / 2.0, 0.0, 0.0, 0.0, 1.0,  -1.0, -1.0,
            -rect_width / 2.0, rect_height / 2.0, 0.0,  0.0, 0.0, 1.0,  -1.0, 2.0
        ], dtype=gl.GLfloat)
        self.indices = np.array([
            0, 1, 3,
            1, 2, 3
        ], dtype=gl.GLuint)
        self.vao = pygl.VertexArrayObject()
        self.vbo = pygl.VertexBufferObject(vertices)
        self.ebo = pygl.ElementBufferObject(self.indices)
        binding_point = 0
        self.vao.setVertexBuffer(self.vbo, binding_point, 0, 
                                 8 * gl.sizeof(gl.GLfloat))
        self.vao.setElementBuffer(self.ebo)
        attribute_position = pygl.VertexAttribute("position", 0, 3, 
                                                  gl.GL_FLOAT, False, 0)
        attribute_color = pygl.VertexAttribute("color",1, 3, 
                        gl.GL_FLOAT, False, 3 * gl.sizeof(gl.GLfloat))
        attribute_tex_coord = pygl.VertexAttribute("tex_coord",2, 2, 
                        gl.GL_FLOAT, False, 6 * gl.sizeof(gl.GLfloat))
        self.vao.setVertexAttribute(binding_point, attribute_position)
        self.vao.setVertexAttribute(binding_point, attribute_color)
        self.vao.setVertexAttribute(binding_point, attribute_tex_coord)

        self.tex = pygl.ImageTexture2D("textures/cratetex_text.png")
        self.wrap_s_mode = gl.GL_CLAMP_TO_EDGE
        self.wrap_t_mode = gl.GL_CLAMP_TO_EDGE
        self.border_color = glm.vec4(0.0, 0.0, 1.0, 1.0)
        self.imgui_window_width = 230
        self.imgui_window_height = 290
        self.tex.setFiltering(gl.GL_NEAREST, gl.GL_LINEAR)

    # 配置imgui界面元素
    def showImGui(self)->None:
        imgui.begin("设置")
        imgui.text("水平环绕GL_TEXTURE_WRAP_S")
        if imgui.radio_button("水平GL_REPEAT", self.wrap_s_mode == gl.GL_REPEAT):
            self.wrap_s_mode = gl.GL_REPEAT
        if imgui.radio_button("水平GL_MIRRORED_REPEAT", self.wrap_s_mode == 
                              gl.GL_MIRRORED_REPEAT):
            self.wrap_s_mode = gl.GL_MIRRORED_REPEAT
        if imgui.radio_button("水平GL_CLAMP_TO_EDGE", self.wrap_s_mode == 
                              gl.GL_CLAMP_TO_EDGE):
            self.wrap_s_mode = gl.GL_CLAMP_TO_EDGE
        if imgui.radio_button("水平GL_CLAMP_TO_BORDER", self.wrap_s_mode == 
                              gl.GL_CLAMP_TO_BORDER):
            self.wrap_s_mode = gl.GL_CLAMP_TO_BORDER
        imgui.text("垂直环绕GL_TEXTURE_WRAP_T")
        if imgui.radio_button("垂直GL_REPEAT", self.wrap_t_mode == gl.GL_REPEAT):
            self.wrap_t_mode = gl.GL_REPEAT
        if imgui.radio_button("垂直GL_MIRRORED_REPEAT", self.wrap_t_mode == 
                              gl.GL_MIRRORED_REPEAT):
            self.wrap_t_mode = gl.GL_MIRRORED_REPEAT
        if imgui.radio_button("垂直GL_CLAMP_TO_EDGE", self.wrap_t_mode == 
                              gl.GL_CLAMP_TO_EDGE):
            self.wrap_t_mode = gl.GL_CLAMP_TO_EDGE
        if imgui.radio_button("垂直GL_CLAMP_TO_BORDER", self.wrap_t_mode == 
                              gl.GL_CLAMP_TO_BORDER):
            self.wrap_t_mode = gl.GL_CLAMP_TO_BORDER
        self.tex.setWrapMode(self.wrap_s_mode, self.wrap_t_mode)
        imgui.end()     

    # 渲染图形
    def render(self) -> None:
        gl.glClearNamedFramebufferfv(0, gl.GL_COLOR, 0, self.background_color.to_tuple())
        self.program.use()
        self.vao.bind()
        if self.wrap_s_mode == gl.GL_CLAMP_TO_BORDER or \
                self.wrap_t_mode == gl.GL_CLAMP_TO_BORDER:
            self.tex.setBorderColor(self.border_color)
        self.program.setUniform1i(1, 2)
        self.tex.bind(0)
        gl.glDrawElements(gl.GL_TRIANGLES, len(self.indices), 
                            gl.GL_UNSIGNED_INT, None)

    # 释放资源
    def cleanup(self) -> None:
        self.tex.delete()
        self.vbo.delete()
        self.ebo.delete()
        self.vao.delete()
        self.program.delete()

if __name__ == "__main__":
    app = TextureWrapApp(100, 100, 800, 600, "你好，纹理环绕App！")
    app.run()

